import sys
import wmi
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QTextEdit, 
                            QPushButton, QLabel, QHBoxLayout, QMessageBox)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont

class SystemInfoApp(QWidget):
    def __init__(self):
        super().__init__()
        self.wmi_client = wmi.WMI()
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle('系统信息查看器')
        self.setGeometry(300, 300, 450, 350)  # 调整整体窗口高度
        
        # 设置统一的字体样式
        self.default_font = QFont('Microsoft YaHei', 9)  # 调小字体
        self.setFont(self.default_font)
        
        # 创建顶部按钮布局
        top_layout = QHBoxLayout()
        self.refresh_btn = QPushButton('刷新信息', self)
        self.refresh_btn.clicked.connect(self.refresh_info)
        self.copy_all_btn = QPushButton('复制全部信息', self)
        self.copy_all_btn.clicked.connect(self.copy_all_to_clipboard)
        
        for btn in [self.refresh_btn, self.copy_all_btn]:
            btn.setStyleSheet("""
                QPushButton {
                    padding: 5px 15px;
                    background-color: #f0f0f0;
                    border: 1px solid #dcdcdc;
                    border-radius: 3px;
                }
                QPushButton:hover {
                    background-color: #e0e0e0;
                }
                QPushButton:pressed {
                    background-color: #d0d0d0;
                }
            """)
            top_layout.addWidget(btn)
        
        # 创建信息显示区域
        self.create_info_area()
        
        # 主布局
        main_layout = QVBoxLayout()
        main_layout.addLayout(top_layout)
        main_layout.addWidget(self.mac_label)
        main_layout.addWidget(self.mac_text)
        main_layout.addWidget(self.disk_label)
        main_layout.addWidget(self.disk_text)
        main_layout.setSpacing(10)
        main_layout.setContentsMargins(15, 15, 15, 15)
        
        self.setLayout(main_layout)
        self.get_system_info()
        
    def create_info_area(self):
        # 创建网卡信息显示区域
        self.mac_label = QLabel('网卡信息:', self)
        self.mac_text = QTextEdit(self)
        self.mac_text.setReadOnly(True)
        self.mac_text.setMaximumHeight(100)  # 限制网卡信息显示区域的高度
        
        # 创建硬盘信息显示区域
        self.disk_label = QLabel('硬盘信息:', self)
        self.disk_text = QTextEdit(self)
        self.disk_text.setReadOnly(True)
        self.disk_text.setMaximumHeight(100)  # 限制硬盘信息显示区域的高度
        
        # 设置样式
        for widget in [self.mac_label, self.disk_label]:
            widget.setStyleSheet("font-weight: bold; color: #333;")
        
        for widget in [self.mac_text, self.disk_text]:
            widget.setStyleSheet("""
                QTextEdit {
                    background-color: #ffffff;
                    border: 1px solid #dcdcdc;
                    border-radius: 3px;
                    padding: 3px;
                }
            """)
    
    def get_system_info(self):
        try:
            mac_address = self.get_mac_address()
            disk_info = self.get_disk_info()
            
            self.mac_text.setText(mac_address or "未找到网卡信息")
            self.disk_text.setText(disk_info or "未找到硬盘信息")
        except Exception as e:
            QMessageBox.warning(self, '错误', f'获取系统信息时出错：{str(e)}')
    
    def get_mac_address(self):
        try:
            macs = []
            for nic in self.wmi_client.Win32_NetworkAdapter():
                if self.is_valid_network_adapter(nic):
                    display_name = self.format_network_name(nic)
                    macs.append(f"网卡型号: {display_name}\n"
                              f"MAC地址: {nic.MACAddress}")  # 移除连接名称
            return "\n\n".join(macs)
        except Exception as e:
            raise Exception(f"获取网卡信息失败: {str(e)}")
    
    @staticmethod
    def format_disk_info(disk, interface):
        return (f"型号: {disk.Model}\n"
                f"序列号: {disk.SerialNumber.strip() if disk.SerialNumber else '未知'}\n"
                f"容量: {int(disk.Size) // (1024**3)}GB")  # 移除接口信息
    
    @staticmethod    # 删除前面的"gq"，修正缩进
    def is_valid_network_adapter(nic):
        virtual_keywords = ['vmware', 'virtualbox', 'virtual', 'pseudo', 'tap', 'tunnel', 'vpn']
        return (nic.PhysicalAdapter or False) and \
               nic.MACAddress and \
               nic.NetConnectionID and \
               not any(x in nic.Name.lower() for x in virtual_keywords) and \
               not any(x in (nic.Description or '').lower() for x in ['virtual', 'pseudo', 'vpn']) and \
               (nic.ProductName or '').strip() != ''
    
    @staticmethod
    def format_network_name(nic):
        return (nic.Name if nic.Name == nic.ProductName 
                else f"{nic.Name}\n产品名称: {nic.ProductName}")
    
    def get_disk_info(self):
        try:
            disks = []
            for disk in self.wmi_client.Win32_DiskDrive():
                interface = self.determine_disk_interface(disk)
                info = self.format_disk_info(disk, interface)
                disks.append(info)
            return "\n\n".join(disks)
        except Exception as e:
            raise Exception(f"获取硬盘信息失败: {str(e)}")
    
    def determine_disk_interface(self, disk):
        interface = disk.InterfaceType
        
        if 'NVMe' in disk.Model or 'NVMe' in str(disk.Caption):
            return 'NVMe'
        elif interface in ['IDE', 'SCSI']:
            if 'SATA' in str(disk.Caption) or 'SATA' in str(disk.Description):
                return 'SATA'
            elif any(bus.BusType == 17 for bus in self.wmi_client.Win32_Bus()):
                if 'SSD' in disk.Model:
                    return 'M.2'
        return interface
    
    def refresh_info(self):
        self.get_system_info()
        QMessageBox.information(self, '提示', '信息已刷新')
    
    def copy_all_to_clipboard(self):
        try:
            mac_text = self.mac_text.toPlainText()
            disk_text = self.disk_text.toPlainText()
            all_text = f"网卡信息:\n{mac_text}\n\n硬盘信息:\n{disk_text}"
            QApplication.clipboard().setText(all_text)
            QMessageBox.information(self, '提示', '信息已复制到剪贴板')
        except Exception as e:
            QMessageBox.warning(self, '错误', f'复制信息时出错：{str(e)}')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle('Fusion')  # 使用Fusion风格获得更现代的外观
    ex = SystemInfoApp()
    ex.show()
    sys.exit(app.exec_())